package com.bookstore.service.impl;

import com.bookstore.dto.UserDTO;
import com.bookstore.entity.User;
import com.bookstore.repository.UserRepository;
import com.bookstore.security.JwtTokenProvider;
import com.bookstore.service.AdminUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;

@Service
public class AdminUserServiceImpl extends BaseServiceImpl<User, UserDTO, Long, UserRepository> implements AdminUserService {
    
    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    private AuthenticationManager authenticationManager;
    @Autowired
    private JwtTokenProvider jwtTokenProvider;

    @Autowired
    private UserRepository userRepository;
    
    public AdminUserServiceImpl(UserRepository repository) {
        super(repository);
    }

    @Override
    public UserDTO login(String username, String password) {
        try {

            // 使用Spring Security进行身份验证
            Authentication authentication = authenticationManager.authenticate(
                new UsernamePasswordAuthenticationToken(username, password)
            );

            // 设置认证信息到上下文
            SecurityContextHolder.getContext().setAuthentication(authentication);

            // 获取认证用户
            User user = (User) authentication.getPrincipal();

            // 检查是否是管理员
            if (user.getRole().join(",").contains("ADMIN")) {
                return null; // 非管理员不允许登录
            }

            // 生成JWT令牌
            String token = jwtTokenProvider.generateToken(user);

            // 转换为DTO并设置token
            UserDTO userDTO = convertToDTO(user);
            userDTO.setToken(token);
            
            return userDTO;
        } catch (Exception e) {
            return null;
        }
    }

    @Override
    public UserDTO getCurrentUser() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication != null && authentication.isAuthenticated() && 
            authentication.getPrincipal() instanceof User) {
            User user = (User) authentication.getPrincipal();
            return convertToDTO(user);
        }
        return null;
    }

    @Override
    public void logout() {
        // 清除Spring Security上下文
        SecurityContextHolder.clearContext();
    }

    @Override
    public boolean changePassword(String oldPassword, String newPassword) {
        // 获取当前用户
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication == null || !authentication.isAuthenticated() || 
            !(authentication.getPrincipal() instanceof User)) {
            return false;
        }
        
        User currentUser = (User) authentication.getPrincipal();
        
        // 验证旧密码
        if (!passwordEncoder.matches(oldPassword, currentUser.getPassword())) {
            return false;
        }
        
        // 更新密码
        currentUser.setPassword(passwordEncoder.encode(newPassword));
        userRepository.save(currentUser);
        
        return true;
    }
    
    @Override
    protected UserDTO convertToDTO(User user) {
        if (user == null) {
            return null;
        }
        
        UserDTO dto = new UserDTO();
        dto.setId(user.getId());
        dto.setUsername(user.getUsername());
        dto.setEmail(user.getEmail());
        dto.setNickname(user.getNickname());
        dto.setPhone(user.getPhone());
        dto.setAddress(user.getAddress());
        dto.setProvince(user.getProvince());
        dto.setCity(user.getCity());
        dto.setDistrict(user.getDistrict());
        dto.setZipCode(user.getZipCode());
        dto.setRole(user.getRole());
        // 出于安全考虑，不设置密码
        
        return dto;
    }
    
    @Override
    protected User convertToEntity(UserDTO dto) {
        User user = new User();
        updateEntity(user, dto);
        
        // 设置创建时间和默认密码
        user.setCreatedAt(LocalDateTime.now());
        if (dto.getPassword() != null && !dto.getPassword().isEmpty()) {
            user.setPassword(passwordEncoder.encode(dto.getPassword()));
        } else {
            // 设置默认密码
            user.setPassword(passwordEncoder.encode("123456"));
        }
        
        return user;
    }
    
    @Override
    protected void updateEntity(User user, UserDTO dto) {
        // 更新用户名前检查是否已存在
        if (dto.getUsername() != null && !dto.getUsername().equals(user.getUsername())) {
            if (repository.existsByUsername(dto.getUsername())) {
                throw new RuntimeException("用户名已存在");
            }
            user.setUsername(dto.getUsername());
        }
        
        // 更新邮箱前检查是否已存在
        if (dto.getEmail() != null && !dto.getEmail().equals(user.getEmail())) {
            if (repository.existsByEmail(dto.getEmail())) {
                throw new RuntimeException("邮箱已被注册");
            }
            user.setEmail(dto.getEmail());
        }
        
        // 更新其他字段
        if (dto.getNickname() != null) {
            user.setNickname(dto.getNickname());
        }
        if (dto.getPhone() != null) {
            user.setPhone(dto.getPhone());
        }
        if (dto.getAddress() != null) {
            user.setAddress(dto.getAddress());
        }
        if (dto.getProvince() != null) {
            user.setProvince(dto.getProvince());
        }
        if (dto.getCity() != null) {
            user.setCity(dto.getCity());
        }
        if (dto.getDistrict() != null) {
            user.setDistrict(dto.getDistrict());
        }
        if (dto.getZipCode() != null) {
            user.setZipCode(dto.getZipCode());
        }
        if (dto.getRole() != null) {
            user.setRole(dto.getRole());
        }
        
        // 如果提供了新密码，则更新密码
        if (dto.getPassword() != null && !dto.getPassword().isEmpty()) {
            user.setPassword(passwordEncoder.encode(dto.getPassword()));
        }
    }
}